import os
import queue
import threading
import tkinter as tk
from tkinter import filedialog

class FileSearcher:
    def __init__(self, search_path, search_str):
        self.search_path = search_path
        self.search_str = search_str
        self.exclude_exts = {'.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff', \
                             '.avi', '.mp4', '.mkv', '.mov', '.wmv', '.flv', '.f4v', '.rmvb', '.rm', '.asf', '.mpeg', '.mpg', '.mpe', '.vob', '.dat', '.ts', \
                             '.exe', '.dll', '.pyc', '.class', '.bin'}
        self.exclude_dirs = {'$RECYCLE.BIN', 'System Volume Information'}
        self.file_queue = queue.Queue()
        self.lock = threading.Lock()
        self.result = set()

    def search_files(self):
        for foldername, subfolders, filenames in os.walk(self.search_path):
            # 排除不需要搜索的文件夹
            subfolders[:] = [sf for sf in subfolders if sf not in self.exclude_dirs]
            for filename in filenames:
                if not any(filename.lower().endswith(ext) for ext in self.exclude_exts):
                    self.file_queue.put(os.path.join(foldername, filename))

    def read_file(self):
        while True:
            try:
                file_path = self.file_queue.get(block=False)
            except queue.Empty:
                break
            with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
                if self.search_str in f.read():
                    with self.lock:
                        self.result.add(file_path)

    def run(self):
        self.search_files()
        threads = [threading.Thread(target=self.read_file) for _ in range(8)]
        for thread in threads:
            thread.start()
        for thread in threads:
            thread.join()

class Application(tk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.grid()
        self.create_widgets()

    def create_widgets(self):
        # 创建“搜索路径”标签和文本框，用于输入搜索路径
        self.path_label = tk.Label(self, text="搜索路径:")
        self.path_label.grid(row=0, column=0, sticky=tk.W)
        self.path_text = tk.Entry(self)
        self.path_text.grid(row=0, column=1, columnspan=2, sticky=tk.W+tk.E)

        # 创建“浏览”按钮，用于选择搜索路径
        self.browse_button = tk.Button(self, text="浏览", command=self.on_browse_button_click)
        self.browse_button.grid(row=0, column=3)

        # 创建“查找内容”标签和文本框，用于输入要查找的内容
        self.keyword_label = tk.Label(self, text="查找内容:")
        self.keyword_label.grid(row=1, column=0, sticky=tk.W)
        self.keyword_text = tk.Entry(self)
        self.keyword_text.grid(row=1, column=1, columnspan=2, sticky=tk.W+tk.E)

        # 创建“搜索”按钮，用于执行搜索操作
        self.search_button = tk.Button(self, text="搜索", command=self.on_search_button_click)
        self.search_button.grid(row=2, column=0, sticky=tk.W)

        # 创建“结果”标签和列表框，用于显示搜索结果
        self.result_label = tk.Label(self, text="结果:")
        self.result_label.grid(row=3, column=0, sticky=tk.W)
        self.result_listbox = tk.Listbox(self, width=80)
        self.result_listbox.grid(row=4, column=0, columnspan=4)

    def on_browse_button_click(self):
        # 打开文件选择对话框并获取用户选择的路径
        path = filedialog.askdirectory()
        if path:
            self.path_text.delete(0, tk.END)
            self.path_text.insert(0, path)

    def on_search_button_click(self):
        # 获取用户输入的搜索路径和搜索内容
        search_path = self.path_text.get()
        search_str = self.keyword_text.get()

        # 执行文件搜索操作，并将搜索结果显示在列表框中
        searcher = FileSearcher(search_path, search_str)
        searcher.run()
        self.result_listbox.delete(0, tk.END)
        for path in sorted(searcher.result):
            self.result_listbox.insert(tk.END, path)

if __name__ == '__main__':
    # 创建主窗口，并启动应用程序
    root = tk.Tk()
    root.title("文件搜索工具")
    app = Application(root)
    app.mainloop()